package logger

import (
	"fmt"
	"runtime"
	"strings"

	"go.uber.org/zap"
)

// H 日志记录Field
type H []interface{}

var sugaredLogger *zap.SugaredLogger

// SetLogger 设置日志记录器实例
func SetLogger(logger *zap.SugaredLogger) {
	sugaredLogger = logger
}

// GetLogger 获取日志记录器实例
func GetLogger() *zap.SugaredLogger {
	return sugaredLogger
}

func Debugf(class string, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, H{})...).Debugf(template, args...)
}

func DebugfWith(class string, fields H, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, fields)...).Debugf(template, args...)
}

func Infof(class string, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, H{})...).Infof(template, args...)
}

func InfofWith(class string, fields H, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, fields)...).Infof(template, args...)
}

func Warnf(class string, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, H{})...).Warnf(template, args...)
}

func WarnfWith(class string, fields H, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, fields)...).Warnf(template, args...)
}

func Errorf(class string, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, H{})...).Errorf(template, args...)
}

func ErrorfWith(class string, fields H, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, fields)...).Errorf(template, args...)
}

func Fatalf(class string, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, H{})...).Fatalf(template, args...)
}

func FatalfWith(class string, fields H, template string, args ...interface{}) {
	sugaredLogger.With(genFields(class, fields)...).Fatalf(template, args...)
}

func genFields(class string, fields H) []interface{} {
	return append(fields, "file", caller(), "class", class)
}

// caller 获取调用日志记录的代码文件行数信息
func caller() string {
	if _, file, line, ok := runtime.Caller(3); ok {
		idx := strings.LastIndexByte(file, '/')
		if idx == -1 {
			return fmt.Sprintf("%s:%d", file, line)
		}
		// Find the penultimate separator.
		idx = strings.LastIndexByte(file[:idx], '/')
		if idx == -1 {
			return fmt.Sprintf("%s:%d", file, line)
		}
		return fmt.Sprintf("%s:%d", file[idx+1:], line)
	}

	return "???:???"
}

type GormLogger struct {
}

func (l *GormLogger) Printf(template string, args ...interface{}) {
	// 1个参数： level，表示这个是个什么请求，可以是“sql”
	// 2个参数：打印sql的代码行号，如/root/mobile-pay-service-golang/app/models/orders.go:83,
	// 3个参数: 执行时间戳
	// 4个参数: sql语句
	// 5参数：如果有预处理，请求参数，第六个参数是这个sql影响的行数。

	var msg string
	var res = make([]interface{}, 0)
	argsCount := len(args)
	if argsCount > 0 {
		res = append(res, zap.Any("file", args[0]))
	}
	if argsCount > 1 {
		msg = fmt.Sprintf("%v", args[1])
	}
	if argsCount > 2 {
		res = append(res, zap.Any("duration", args[2]))
	}
	if argsCount > 3 {
		res = append(res, zap.Any("sql", args[3]))
	}
	if argsCount > 4 {
		res = append(res, zap.Any("values", args[4]))
	}
	if argsCount > 5 {
		res = append(res, zap.Any("rows_returned", args[5]))
	}

	sugaredLogger.With("class", "iec104").Infow(msg, res...)
}
